package com.wang.tool.monitor.aop;

import com.wang.tool.monitor.callback.MonitorCallback;
import com.wang.tool.monitor.weaver.TypeWeaver;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author shaopeng
 * @Date 2022/7/23
 * @Version 1.0
 */
public class MonitorRegister implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes monitorAttr = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableMonitor.class.getName()));
        int order = monitorAttr.getNumber("order");
        BeanDefinitionBuilder orderBuilder = BeanDefinitionBuilder.genericBeanDefinition(MonitorAdvisorOrder.class);
        orderBuilder.addPropertyValue("order", order);
        registry.registerBeanDefinition("monitorAdvisorOrder1", orderBuilder.getBeanDefinition());


        //logApi
        BeanDefinitionBuilder fetcherBuilder = BeanDefinitionBuilder.genericBeanDefinition(monitorAttr.getClass("logApi"));
        registry.registerBeanDefinition(SpringMonitorConfigSetter.SPRING_LOG_API_NAME, fetcherBuilder.getBeanDefinition());

        //异常
        BeanDefinitionBuilder translatorBuilder = BeanDefinitionBuilder.genericBeanDefinition(monitorAttr.getClass("errorTranslator"));
        registry.registerBeanDefinition(SpringMonitorConfigSetter.SPRING_GLOBAL_ERROR_TRANSLATOR_NAME, translatorBuilder.getBeanDefinition());

        //writer
        BeanDefinitionBuilder writerBuilder = BeanDefinitionBuilder.genericBeanDefinition(monitorAttr.getClass("monitorWriter"));
        registry.registerBeanDefinition(SpringMonitorConfigSetter.SPRING_GLOBAL_MONITOR_WRITER_NAME, writerBuilder.getBeanDefinition());

        //回调
        Class<?> callbackType = monitorAttr.getClass("callback");
        if (!callbackType.equals(MonitorCallback.class)) {
            BeanDefinitionBuilder callbackBuilder = BeanDefinitionBuilder.genericBeanDefinition(callbackType);
            registry.registerBeanDefinition(SpringMonitorConfigSetter.SPRING_MONITOR_CALLBACK_NAME, callbackBuilder.getBeanDefinition());
        }


        //链路传送器
        BeanDefinitionBuilder transmitterBuilder = BeanDefinitionBuilder.genericBeanDefinition(monitorAttr.getClass("transmitter"));
        registry.registerBeanDefinition(SpringMonitorConfigSetter.SPRING_LINK_TRANSMITTER_NAME, transmitterBuilder.getBeanDefinition());


        //类型编织器
        List<Class<?>> typeWeavers = Arrays.stream(monitorAttr.getClassArray("typeWeavers")).filter(t -> !t.equals(TypeWeaver.class)).collect(Collectors.toList());
        for (int i = 0; i < typeWeavers.size(); i++) {
            Class<?> typeWeaver = typeWeavers.get(i);
            BeanDefinitionBuilder typeWeaverBuilder = BeanDefinitionBuilder.genericBeanDefinition(typeWeaver);
            registry.registerBeanDefinition(SpringMonitorConfigSetter.SPRING_TYPE_WEAVER_NAME_PREFIX + i, typeWeaverBuilder.getBeanDefinition());
        }
    }
}
